import numpy  as np


def simple_opera():
    """
    数组的基本四则运算
    :return:
    """
    base_arr = np.arange(24).reshape(4, 6)

    # 数组的加法
    add_arr_1 = np.arange(1, 25).reshape(4, 6)  # 行和列相同的数组相加，对应的元素每个两两相加
    rs_1 = base_arr + add_arr_1
    # print(base_arr)
    # print(add_arr_1)
    # print(rs_1)

    add_arr_2 = np.arange(6).reshape(6, )  # 行相同，则数组的每行都相加
    rs_2 = base_arr + add_arr_2
    # print(base_arr)
    # print(add_arr_2)
    # print(rs_2)
    add_arr_3 = np.arange(4).reshape(4, 1)  # 列相同，行不相同,则数组的每列都相加
    rs_3 = base_arr + add_arr_3
    # print(base_arr)
    # print(add_arr_3)
    # print(rs_3)

    rs_4 = base_arr ** 2  # 乘方运算，所有元素都会计算
    print(rs_4)


def one_opera():
    """
    一元操作
    :return: None
    """
    base_arr = np.arange(24).reshape(4, 6)
    sum_arr = base_arr.sum()
    sum_arr_axis = base_arr.sum(axis=0)  # 指定轴相加
    cumsum_arr = base_arr.cumsum();
    cumsum_arr_axis = base_arr.cumsum(axis=0);
    print(base_arr)
    # print(sum_arr)
    # print(sum_arr_axis)
    # print(cumsum_arr)
    print(cumsum_arr_axis)


def ufunc():
    """
    通函数
    :return:None
    """
    base_arr = np.arange(9).reshape(3, 3)
    exp_arr = np.all(base_arr)
    print(base_arr)
    print(exp_arr)


def slice_arr():
    """
    数组切片、索引和迭代
    :return:
    """
    one_arr = np.array(range(20)).reshape(4, 5)
    print("one_arr:\n", one_arr)
    # 取行
    # print("*" * 50 + "取指定的行" + "*" * 50)
    # print("one_arr[2]:\n", one_arr[2])  # 取指定的行
    # print("*" * 50 + "取连续的行" + "*" * 50)
    # print("one_arr[2:6]:\n", one_arr[2:6])  # 算头不算尾
    # print("one_arr[:6]:\n", one_arr[:6])  # beg缺省，默认为0
    # print("one_arr[2:]:\n", one_arr[2:])  # end缺省，默认为数组最后
    # print("*" * 50 + "取非连续的行" + "*" * 50)
    # print("one_arr[[0,2,3]]:\n", one_arr[[0, 2, 3]])
    # 取列
    # print("*" * 50 + "取指定的列" + "*" * 50)
    # print("one_arr[:,2]:\n", one_arr[:, 2])  # 取指定的列
    # print("*" * 50 + "取连续的列" + "*" * 50)
    # print("one_arr[:,1:4]:\n", one_arr[:, 1:4])
    # print("one_arr[:, :4]:\n", one_arr[:, :4])
    # print("one_arr[:, 1:]:\n", one_arr[:, 1:])
    # print("*" * 50 + "取非连续的列" + "*" * 50)
    # print("one_arr[:, [0,2,4]]:\n", one_arr[:, [0, 2, 4]])
    # 取行和列
    # print("*" * 50 + "取指定的行和列" + "*" * 50)
    # print("one_arr[3,2]:\n", one_arr[3, 2])
    # print("one_arr[0:3,2:5]:\n", one_arr[0:3, 2:5])
    # print("one_arr[:,[1,2,4]]:\n", one_arr[:, [1, 2, 4]])
    # 取非连续的点
    # print("*" * 50 + "取非连续的点" + "*" * 50)
    # print("one_arr[[1, 2, 3], [1, 2, 4]:\n", one_arr[[1, 2, 3], [1, 2, 4]])
    # 设定切片的步长
    # equivalent to a[0:6:2] = -1000; from start to position 6, exclusive, set every 2nd element to -1000
    one_arr[:6:2] = -1000
    print("one_arr after one_arr[:6:2] = -1000 :\n", one_arr)
    print("one_arr[:,:2:2] :\n", one_arr[:, :2:2])


def f(x, y):
    return 10 * x + y


def complex_slice_arr():
    b = np.fromfunction(f, (5, 4), dtype=int)
    print("b:", b)
    print("b[2,3]:", b[2, 3])
    print("b[0:5,1]:", b[0:5, 1])  # each row in the second column of b
    print("b[:,0]:", b[:, 4])  # equivalent to the previous example


def re_shape():
    """
    改变数组的形状
    :return:
    """
    base_arr = np.arange(20).reshape(4, 5)
    ravel_arr = base_arr.ravel()  # returns the array, flattened
    flatten_arr = base_arr.flatten()
    print("base_arr：", base_arr)
    print("*" * 30)
    print("ravel_arr:", ravel_arr)
    print("flatten_arr:", flatten_arr)
    t_arr = base_arr.T
    print("*" * 30)
    print("t_arr:", t_arr)
    transpose_arr = t_arr.transpose()
    print("*" * 30)
    print("transpose_arr:", transpose_arr)


def stack_and_split():
    """
    数组的合并与拆分
    :return: None
    """
    base_a = np.arange(20).reshape(4, 5)
    base_b = np.arange(15).reshape(3, 5)
    base_d = np.arange(1, 17).reshape(4, 4)
    v_c_arr = np.vstack((base_a, base_b))
    h_c_arr = np.hstack((base_a, base_d))
    print("base_a:\n", base_a)
    print("base_b:\n", base_b)
    print("*" * 50 + "数组的纵向合并" + "*" * 50)
    print("v_c_arr:\n", v_c_arr)
    print("*" * 50 + "数组的横向合并" + "*" * 50)
    print("h_c_arr:\n", h_c_arr)
    print("*" * 50 + "数组的纵向拆分" + "*" * 50)
    print("np.vsplit(v_c_arr,3):\n", np.vsplit(v_c_arr, (2, 3)))


def view_and_copy():
    """
    拷贝与视图
    :return: None
    """
    # 视图和浅拷贝,不同的数组对象可以共享相同的数据
    base_arr = np.arange(20).reshape(4, 5)
    base_arr_view = base_arr.view()
    base_arr_same = base_arr
    base_arr_b = np.floor(10 * np.random.random((2, 12)))
    print("*" * 50 + "视图和浅拷贝" + "*" * 50)
    print("base_arr:\n", base_arr)
    print("base_arr.flags.owndata:\n", base_arr.flags.owndata)
    print("base_arr_view:\n", base_arr_view)
    print("base_arr_view == base_arr：\n", base_arr == base_arr_view)
    print("base_arr_same is base_arr：\n", base_arr_same is base_arr)
    print("base_arr_view is base_arr：\n", base_arr_view is base_arr)
    print("base_arr_view is owndata：\n", base_arr_view.flags.owndata)
    print("base_arr is owndata：\n", base_arr.flags.owndata)
    print("base_arr.base：\n", base_arr.base)
    print("base_arr_view.base：\n", base_arr_view.base)
    print("base_arr_same.base：\n", base_arr_same.base)
    print("*" * 50 + "数组的owndata" + "*" * 50)
    # The array owns the memory it uses or borrows it from another object
    print("base_arr_b.base：\n", base_arr_b.base)
    print("base_arr_b：\n", base_arr_b)
    print("base_arr_b is owndata：\n", base_arr_b.flags.owndata)

    print("*" * 50 + "数组的深度拷贝" + "*" * 50)
    base_arr_copy = base_arr.copy()
    print("base_arr_copy.base is base_arr:\n", base_arr_copy.base is base_arr)
    print("base_arr.flags.owndata:\n", base_arr.flags.owndata)
    print("base_arr_copy.flags.owndata:\n", base_arr_copy.flags.owndata)


if __name__ == "__main__":
    # simple_opera()
    # one_opera()
    # ufunc()
    # slice_arr()
    # complex_slice_arr()
    # re_shape()
    # stack_and_split()
    view_and_copy()
